/*
** Test CGA by Neil C. Obremski                               [ Magenta's Maze ]
** 2017 Gibdon Moon Productions                   [ http://magsmaze.gibdon.com ]
**
** This is free and unencumbered software released into the public domain.
**
** Anyone is free to copy, modify, publish, use, compile, sell, or
** distribute this software, either in source code form or as a compiled
** binary, for any purpose, commercial or non-commercial, and by any
** means.
**
** In jurisdictions that recognize copyright laws, the author or authors
** of this software dedicate any and all copyright interest in the
** software to the public domain. We make this dedication for the benefit
** of the public at large and to the detriment of our heirs and
** successors. We intend this dedication to be an overt act of
** relinquishment in perpetuity of all present and future rights to this
** software under copyright law.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
** IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
** OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
** ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
** OTHER DEALINGS IN THE SOFTWARE.
**
** Tested w/ DOSBox 0.74, Microsoft C 5.10
 */
#include <conio.h>	/* getch() */
#include <stdio.h>	/* printf() */
#include <stdlib.h>

#include "mag-cga.h"
#include "mag-bios.h"
#include "mag-logo.h"

int test_cls(int);
int test_pset(int);
int test_font(int);
int test_hline(int);
int test_trifill(int);
int test_line(int);
int test_logo(int);

int main(int argc, char *argv[])
{
	int mainloop, loopmax = 100, keeploop = 1, mode = 0, test = 0, scancode = 0;

	if (argc > 1) {
		if (0 == memcmp("AUTO", argv[1], 4)) {
			test = argv[1][4] - '0';
		} else {
			test = argv[1][0];
		}
	}

	puts("\nEnter Test To Run:");
	puts("1.> PSET");
	puts("2.> HLINE");
	puts("3.> TRIFILL");
	puts("4.> FONT");
	puts("5.> CLS");
	puts("6.> LINE");
	puts("7.> LOGO");
	puts("Q.> QUIT");

	if (test < 1 || test > 32) {
		test = scancode = getch();
	}

	mode = screen(4);

	for (mainloop = 0; 'q' != (char)scancode && keeploop && mainloop < loopmax; mainloop++) {

		switch (test) {

			case '1': case 1:
				keeploop = test_pset(mainloop);
				break;

			case '2': case 2:
				keeploop = test_hline(mainloop);
				break;

			case '3': case 3:
				keeploop = test_trifill(mainloop);
				break;

			case '4': case 4:
				keeploop = test_font(mainloop);
				break;

			case '5': case 5:
				keeploop = test_cls(mainloop);
				break;

			case '6': case 6:
				keeploop = test_line(mainloop);
				break;

			case '7': case 7:
				keeploop = test_logo(mainloop);
				break;

			default: /* unrecognized test */
				keeploop = 0;
				break;
		}

		if (keeploop && 1+mainloop < loopmax && (test < 1 || test > 32)) {
			scancode = getch();
			if (75 == scancode) {
				mainloop--;
			}
		}
	}

	if ('q' != (char)scancode && (test < 1 || test > 32)) {
		test = getch();
	}

	screen(mode);

	return 0;
}

int test_cls(int iteration)
{
	switch (iteration) {
		case 0:
			cls(WHITE);
			break;
		case 1:
			cls(MAGENTA);
			break;
		case 2:
			cls(CYAN);
			break;
		case 3:
			cls(BLACK);
			return 0;
	}

	return 1;
}

int test_pset(int iteration)
{
	iteration;

	pset(0,0,CYAN);
	pset(1,0,MAGENTA);
	pset(2,0,WHITE);

	pset(10,11,CYAN);
	pset(11,11,MAGENTA);
	pset(12,11,WHITE);

	return 0;
}


int test_font(int iteration)
{
	if (0 == iteration) {
		int i;
		unsigned char far *p;
		char x, y;
		int b;

		for (i = 0; i < 256; i++) {
			p = bioschar((unsigned char)i);
			for (y = 0; y < 8; y++) {
				for (x = 0; x < 8; x++) {
					b = FONT_BIT(p,x,y);
					pset(x + (i%30*8),y + (i/30*8), b ? CYAN : BLACK);
				}
			}
		}

		return 1;
	}

	color(CYAN, BLACK);
	textblit(0, 80, "HELLO WORLD!", -1);
	color(BLACK, CYAN);
	textblit(0, 88, "HELLO WORLD!", 20);

	locate(12,0);
	puts("HELLO WORLD!");

	color(MAGENTA, BLACK);
	textblit(0, 104, "THIS WILL BE CLIPPED BEFORE IT FINISHES", 20);
	locate(14,0);
	puts("THIS WILL BE CLIPPED BEFORE IT FINISHES");

	tinyblit(0,120, "0123456789");
	color(WHITE, BLACK);
	textblit(80,120, "0123456789", -1);
	tinyblit(0,125, __DATE__);

	tinyblit(0,130, "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z");

	color(MAGENTA, BLACK);
	titleblit(0,140, "Magenta's Maze", 20);
	color(WHITE, BLACK);
	titleblit(160,140, "(title blit)", 20);

	color(CYAN, BLACK);
	giantc(144, 156, 'G');

	return 0;
}

int test_hline(int iteration)
{
	iteration;

	hline(-10, 0, 10, MAGENTA);

	pset(39, 10, MAGENTA);
	pset(43, 10, MAGENTA);
	hline(40, 42, 10, CYAN);

	pset(79, 10, CYAN);
	pset(103, 10, CYAN);
	hline(80, 102, 10, MAGENTA);

	pset(119, 10, MAGENTA);
	pset(143, 10, MAGENTA);
	hline(142, 120, 10, WHITE);

	pset(39, 20, MAGENTA);
	pset(42, 20, MAGENTA);
	hline(40, 41, 20, CYAN);

	pset(79, 20, CYAN);
	pset(102, 20, CYAN);
	hline(80, 101, 20, MAGENTA);

	pset(119, 20, MAGENTA);
	pset(142, 20, MAGENTA);
	hline(141, 120, 20, WHITE);

	pset(39, 30, MAGENTA);
	pset(41, 30, MAGENTA);
	hline(40, 40, 30, CYAN);

	pset(79, 30, CYAN);
	pset(101, 30, CYAN);
	hline(80, 100, 30, MAGENTA);

	pset(119, 30, MAGENTA);
	pset(141, 30, MAGENTA);
	hline(140, 120, 30, WHITE);

	pset(40, 40, MAGENTA);
	pset(44, 40, MAGENTA);
	hline(41, 43, 40, CYAN);

	pset(80, 40, CYAN);
	pset(104, 40, CYAN);
	hline(81, 103, 40, MAGENTA);

	pset(120, 40, MAGENTA);
	pset(144, 40, MAGENTA);
	hline(143, 121, 40, WHITE);

	pset(40, 50, MAGENTA);
	pset(43, 50, MAGENTA);
	hline(41, 42, 50, CYAN);

	pset(80, 50, CYAN);
	pset(103, 50, CYAN);
	hline(81, 102, 50, MAGENTA);

	pset(120, 50, MAGENTA);
	pset(143, 50, MAGENTA);
	hline(142, 121, 50, WHITE);

	pset(40, 60, MAGENTA);
	pset(42, 60, MAGENTA);
	hline(41, 41, 60, CYAN);

	pset(80, 60, CYAN);
	pset(102, 60, CYAN);
	hline(81, 101, 60, MAGENTA);

	pset(120, 60, MAGENTA);
	pset(142, 60, MAGENTA);
	hline(141, 121, 60, WHITE);

	pset(41, 70, MAGENTA);
	pset(44, 70, MAGENTA);
	hline(42, 43, 70, CYAN);

	pset(81, 70, CYAN);
	pset(104, 70, CYAN);
	hline(82, 103, 70, MAGENTA);

	pset(121, 70, MAGENTA);
	pset(144, 70, MAGENTA);
	hline(143, 122, 70, WHITE);

	pset(41, 80, MAGENTA);
	pset(43, 80, MAGENTA);
	hline(42, 42, 80, CYAN);

	pset(81, 80, CYAN);
	pset(103, 80, CYAN);
	hline(82, 102, 80, MAGENTA);

	pset(121, 80, MAGENTA);
	pset(143, 80, MAGENTA);
	hline(142, 122, 80, WHITE);

	pset(42, 90, MAGENTA);
	pset(44, 90, MAGENTA);
	hline(43, 43, 90, CYAN);

	pset(82, 90, CYAN);
	pset(104, 90, CYAN);
	hline(83, 103, 90, MAGENTA);

	pset(122, 90, MAGENTA);
	pset(144, 90, MAGENTA);
	hline(143, 123, 90, WHITE);

	return 0;
}

int test_trifill(int iteration)
{
	if (iteration < 2) {

		if (1 == iteration) {
			border(BORDER_ALL);
		} else {
			border(0);
		}

		color(MAGENTA, CYAN);

		trifill(167,97, 171,99, 172,115, CYAN);

		logo(0,0,1,1,MAGENTA);

		return 1;
	}

	if (2 == iteration || 4 == iteration) {
		cls(BLACK);
		border(BORDER_ALL);
	}

	if (3 == iteration) {
		border(0);
	}

	if (5 == iteration) {
		cls(BLACK);
		border(0);
	}

	trifill(5,0, 0,10, 10,10, WHITE);

	trifill(-10,20, 0,20, 30,30, CYAN);

	trifill(10,20, 20,20, 50,30, WHITE);

	trifill(20,60, -20,70, 40,70, CYAN);

	trifill(90,60, 50,70, 110,70, WHITE);

	trifill(100,0, 90,50, 110,50, CYAN);

	trifill(150,0, 160,40, 140,50, CYAN);

	trifill(200,0, 190,40, 210,50, CYAN);

	trifill(250,0, 270,10, 260,50, CYAN);

	trifill(271,10, 261,50, 300,30, WHITE);

	trifill(0,100, 80,110, 20,150, CYAN);

	trifill(90,100, 110,100, 100,150, CYAN);

	trifill(190,100, 130,120, 200,150, CYAN);

	trifill(230,100, 290,120, 220,150, CYAN);

	trifill(300,100, 360,120, 290,150, CYAN);

	return iteration < 6 ? 1 : 0;
}

int YON = 100;
int HITHER = 25;

void liney(int x1,int z1, int x2,int z2)
{
	line(160 + x1, 150 - z1, 160 + x2, 150 - z2, MAGENTA);

	if (clipline(&x1,&z1, &x2,&z2, -YON,HITHER, YON,YON)) {
		line(160 + x1, 150 - z1, 160 + x2, 150 - z2, CYAN);
	}
}

int test_line(int iteration)
{
	if (0 == iteration) {
		line(50,50, 70,60, CYAN);
		line(80,50, 90,50, CYAN);

		line(50,70, 60,90, MAGENTA);
		line(70,70, 70,90, MAGENTA);

		line(50,100, 80,130, WHITE);
		line(90,100, 90,100, WHITE);

		/* clipping */
		line(50,-50, 70,40, MAGENTA);
		line(-10,40, 330,50, MAGENTA);
		line(150,-50, 200,250, CYAN);

		/* invisible */
		line(-1,-1, -20,-20, MAGENTA);
		line(320,5, 330,10, CYAN);

		return 1;
	}

	if (1 == iteration) {
		pset(50,50, MAGENTA);
		pset(70,60, MAGENTA);
		pset(80,50, MAGENTA);
		pset(90,50, MAGENTA);

		pset(50,70, CYAN);
		pset(60,90, CYAN);
		pset(70,70, CYAN);
		pset(70,90, CYAN);

		pset(50,100, MAGENTA);
		pset(80,130, MAGENTA);
		pset(90,100, MAGENTA);

		return 1;
	}

	cls(BLACK);

	/* assert bug */
	line(311,-7, 368,24, WHITE);

	/* Y1 intercept when Y1 < Y2 and X1 < 0 */
	line(-10,20, 10,30, MAGENTA);
	line(0,30, 10,35, CYAN);

	/* Y1 intercept when Y2 < Y1 and X1 < 0 */
	line(-10,50, 10,40, MAGENTA);
	line(0,50, 10,45, CYAN);

	/* Y2 intercept when Y1 < Y2 and X2 > 319 */
	line(310,20, 330,30, MAGENTA);
	line(310,30, 319,35, CYAN);

	/* Y2 intercept when Y2 < Y1 and X2 > 319 */
	line(310,50, 330,40, MAGENTA);
	line(310,60, 319,55, CYAN);

	/* X2 intercept when Y2 < 0 and Y2 < Y1 */
	line(10,10, 20,-10, MAGENTA);
	line(30,10, 35,0, CYAN);

	/* X1 intercept when Y1 > 199 and Y2 < Y1 */
	line(10,210, 20,190, MAGENTA);
	line(30,199, 35,190, CYAN);

	/* X1 intercept when Y1 < Y2 and Y1 < 0 */
	line(40,-10, 50,10, MAGENTA);
	line(60,0, 65,10, CYAN);

	/* X2 intercept when Y1 < Y2 and Y2 > 199 */
	line(40,190, 50,210, MAGENTA);
	line(60,190, 65,199, CYAN);

	box(160-YON, 150-HITHER, 160+YON, 150-YON, WHITE);

	liney(-100,-25, 100,120);
	liney(-150,-25, -50,120);
	liney(0,-1000, 0,1000);
	liney(-1000,50, 1000,50);

	return 0;
}

int test_logo(int iteration)
{
	if (0 == iteration) {
		cls(BLACK);
		titles();
		return 1;
	}

	cls(BLACK);
	avatar(0,0);
	return 0;
}
